#include "cnn.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define EN_IMAGE_FILE "en-image-ubyte"
#define EN_LABEL_FILE "en-label-ubyte"
#define ZH_IMAGE_FILE "zh-image-ubyte"
#define ZH_LABEL_FILE "zh-label-ubyte"
#define IMAGE_LENGTH  LENGTH_FEATURE0
#define X -1
#define O +1

static const char enResMat[34][84] =
{
	{ X,X,O,X,O,X,X,O,O,O,X,O,X,X,X,O,X,O,O,O,O,X,X,O,O,O,X,X,O,X,O,O,O,O,X,X,X,O,O,O,O,O,X,X,O,X,O,O,X,X,O,X,X,O,X,X,O,X,O,O,O,O,X,O,O,O,O,X,X,X,O,O,X,X,O,X,X,X,O,O,X,X,X,X },
	{ X,X,X,X,X,X,O,X,O,O,O,X,X,X,O,X,O,X,O,X,X,X,X,O,X,X,X,X,X,O,X,O,X,X,X,O,X,X,X,O,X,O,O,O,O,O,O,X,X,O,O,O,X,O,X,O,X,O,O,X,O,O,X,X,O,X,X,O,O,O,O,O,X,O,O,O,O,X,O,O,O,O,O,O },
	{ O,O,O,O,X,O,X,X,O,X,O,O,O,X,X,X,O,O,X,O,O,X,X,O,O,O,O,X,X,X,O,X,X,X,X,X,X,X,X,X,X,O,X,O,X,O,O,X,O,O,X,O,O,O,O,X,O,X,O,X,O,X,X,X,X,O,X,X,O,O,X,O,O,O,O,X,O,X,O,O,O,O,O,O },
	{ X,X,X,X,X,O,O,O,X,O,O,X,X,O,O,X,O,X,O,X,O,X,O,X,O,X,O,O,X,O,X,X,O,X,X,X,O,X,O,X,X,X,O,X,O,O,O,X,O,X,X,O,X,X,O,X,X,X,X,X,O,X,X,X,X,X,O,X,O,X,O,X,O,O,X,X,O,X,O,O,O,O,X,X },
	{ X,X,X,O,X,X,O,O,X,X,O,O,O,X,O,O,O,X,O,X,X,O,X,X,X,X,X,X,O,O,X,X,O,X,X,O,X,O,O,X,X,X,X,X,X,O,O,O,X,X,O,O,O,X,X,X,X,X,O,O,O,O,X,X,X,X,O,O,X,O,O,X,O,X,X,O,O,O,X,X,O,O,X,O },
	{ X,X,X,X,X,O,O,O,O,X,X,O,X,X,X,O,O,O,O,X,O,X,X,X,O,O,X,X,O,X,O,O,X,X,X,O,X,O,O,X,X,O,O,X,X,O,O,O,O,O,O,X,X,X,X,X,X,O,X,X,O,O,O,X,O,O,X,X,X,O,X,X,O,X,O,X,O,X,O,O,X,O,X,O },
	{ X,X,O,X,O,X,O,X,O,O,X,O,O,O,O,X,X,O,X,X,O,X,X,X,O,O,X,X,X,O,O,X,O,O,O,O,O,X,O,O,O,X,X,O,X,O,O,X,X,X,X,X,O,O,O,X,X,X,O,O,X,O,X,O,O,X,O,X,X,X,O,O,O,X,O,X,X,O,X,X,X,X,X,O },
	{ O,O,X,X,O,X,O,O,O,X,X,X,X,O,O,X,X,O,O,O,X,O,O,X,O,X,O,O,X,O,X,X,X,O,X,X,O,O,O,O,X,X,O,O,X,O,O,X,O,X,X,O,O,X,O,O,O,O,O,X,X,X,X,X,X,O,X,O,O,O,O,O,O,O,O,O,O,X,O,O,X,X,O,X },
	{ O,O,X,X,X,X,O,O,O,X,O,X,X,O,O,O,X,X,O,X,X,X,O,X,X,X,O,X,O,O,X,O,X,X,X,O,O,O,X,O,X,O,X,O,X,X,O,X,O,X,O,O,X,O,X,O,O,X,O,O,X,X,X,X,O,X,O,X,O,O,X,O,X,X,O,O,O,X,X,X,X,X,X,O },
	{ O,X,X,O,X,X,X,X,X,X,O,O,O,O,X,O,X,O,X,X,O,O,X,O,X,X,O,O,O,O,X,O,O,X,O,O,O,O,X,X,X,X,O,X,O,O,O,O,O,X,X,X,O,O,X,X,O,X,O,O,X,X,O,X,O,O,X,X,X,X,X,O,X,X,O,X,X,O,O,O,O,O,O,X },
	{ O,O,X,O,X,X,O,O,O,X,O,O,O,X,O,O,O,O,O,X,O,X,O,X,O,X,X,X,X,X,O,X,O,O,X,X,O,O,X,O,O,X,O,O,X,O,X,X,X,O,X,O,X,O,O,X,X,O,X,X,X,O,X,X,X,X,X,X,O,X,O,X,O,X,O,X,X,X,X,X,O,X,O,X },
	{ X,X,X,O,O,O,X,X,X,O,O,X,O,X,X,X,O,O,X,X,X,X,X,O,O,O,X,O,X,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,X,X,X,X,X,X,O,X,X,O,X,X,X,O,X,O,O,X,O,O,X,X,X,X,X,O,O,X,X,X,O,X,O,O,O,X,O,X },
	{ O,O,O,O,O,X,O,O,O,O,X,O,X,X,O,X,X,X,X,X,O,X,X,X,O,X,X,X,X,X,X,X,O,X,X,X,X,O,O,O,X,O,O,O,O,X,X,X,X,O,O,X,X,O,O,O,O,O,O,X,X,O,X,X,O,X,X,O,O,O,O,X,X,O,X,O,X,O,X,O,X,O,O,O },
	{ X,X,X,X,O,X,O,O,O,O,O,X,O,X,O,X,O,O,O,O,O,O,O,O,O,O,X,X,X,X,O,O,O,O,O,O,X,O,X,X,O,X,O,X,X,X,O,X,X,O,X,O,X,X,X,X,X,O,X,O,O,X,O,O,X,X,O,O,O,X,O,X,O,X,O,X,X,X,X,X,X,X,X,X },
	{ X,X,O,O,X,X,O,X,O,O,O,X,X,X,X,O,O,O,O,X,X,X,O,X,O,X,O,X,X,O,X,O,O,X,O,X,X,X,O,X,O,X,X,O,O,O,X,O,O,O,X,X,X,O,X,X,X,O,X,X,O,O,O,X,O,X,O,O,X,O,X,X,X,X,X,O,O,X,X,O,X,O,O,X },
	{ X,X,O,X,X,O,O,X,X,X,O,O,O,O,O,X,O,O,X,X,X,X,O,X,O,O,X,X,O,O,O,O,O,O,O,X,O,O,X,O,X,X,X,O,X,O,X,O,X,X,X,O,O,X,O,X,X,O,O,O,O,O,O,O,O,X,X,O,O,X,X,X,O,X,O,O,X,X,O,O,X,X,O,X },
	{ X,X,X,X,O,X,X,X,O,O,O,X,O,X,X,O,X,X,O,O,O,X,X,X,O,O,X,O,O,X,O,X,X,X,O,O,X,O,O,X,X,X,O,O,X,X,O,O,X,O,O,X,O,O,X,X,X,O,O,O,O,X,X,X,O,X,X,O,O,O,X,O,X,X,O,O,O,X,X,X,O,X,X,X },
	{ O,X,X,X,X,X,O,O,O,O,X,O,O,X,X,O,O,O,O,X,X,O,O,O,O,O,X,X,O,O,X,X,O,X,O,O,O,O,O,O,O,O,O,X,X,X,X,X,O,O,O,X,X,X,X,X,X,O,X,O,O,X,O,O,X,X,X,O,X,O,X,X,X,O,X,X,X,X,O,X,X,O,X,X },
	{ O,O,X,X,X,X,O,X,O,O,X,O,O,O,O,X,O,X,X,X,X,O,X,X,O,O,X,O,O,X,X,O,X,O,O,O,O,X,O,O,X,O,O,X,O,X,X,X,X,X,X,O,X,X,O,O,X,X,X,X,X,X,X,X,O,X,O,O,O,O,X,O,X,X,X,O,O,X,X,X,O,X,X,O },
	{ O,X,X,X,X,O,O,O,X,X,O,X,X,X,X,X,X,X,O,O,O,O,O,O,O,O,X,X,O,X,O,X,X,X,O,O,X,X,X,X,O,O,O,O,X,X,O,X,X,X,O,O,O,X,O,X,O,X,X,O,X,X,X,O,O,X,O,O,X,X,X,X,O,X,O,O,X,O,O,X,X,O,X,X },
	{ X,X,O,X,O,O,X,O,X,O,X,O,X,X,O,O,X,X,X,O,X,O,X,O,X,X,X,X,X,X,X,O,X,X,O,X,O,X,O,X,O,O,O,O,O,O,X,X,X,X,X,O,O,O,X,O,X,X,X,X,X,X,X,O,X,X,O,X,O,O,O,X,X,O,O,X,X,X,X,O,O,O,X,O },
	{ O,O,O,O,O,O,X,O,O,X,O,O,X,X,X,X,O,O,O,O,O,O,X,X,O,X,X,X,O,O,X,X,X,X,X,O,X,O,X,X,X,X,O,O,O,X,X,O,X,O,O,X,O,O,X,X,X,O,X,O,O,O,O,X,X,O,O,X,X,X,O,O,X,X,O,X,O,O,O,X,O,X,X,X },
	{ X,X,X,X,O,X,X,X,O,O,O,O,O,O,X,O,O,O,X,X,X,X,O,O,X,X,O,O,X,O,O,X,O,O,O,X,X,X,O,X,O,X,O,O,X,X,X,X,O,O,X,O,O,O,O,X,X,O,X,X,O,O,X,O,X,X,O,X,X,O,X,O,O,X,O,O,O,X,X,X,O,X,O,O },
	{ O,O,O,X,X,X,X,X,O,X,O,X,X,X,X,X,X,X,O,O,O,O,O,X,X,X,X,X,O,X,X,X,O,O,X,X,O,X,O,O,X,O,X,O,X,X,X,X,O,O,X,X,O,X,X,X,O,X,X,O,X,O,O,X,O,X,X,O,O,X,O,O,O,X,X,O,X,O,O,O,X,X,O,X },
	{ X,X,X,O,O,X,X,X,O,X,X,X,O,X,X,X,O,X,O,O,O,O,X,X,O,O,O,X,X,O,O,O,X,X,O,O,O,X,X,O,O,X,X,X,O,O,X,O,X,X,X,O,X,O,O,O,O,X,X,O,O,X,O,O,X,O,O,X,O,X,O,X,O,X,X,O,X,O,X,X,X,X,X,O },
	{ X,X,O,O,X,X,O,X,O,X,X,X,X,O,X,X,O,X,O,X,O,X,X,X,X,X,O,X,X,O,X,O,X,O,O,X,O,O,X,O,X,X,X,X,O,O,O,X,O,O,X,X,X,X,O,X,O,X,O,X,X,X,X,X,O,X,X,X,O,O,O,X,O,O,X,X,X,O,O,X,O,X,O,X },
	{ X,X,X,O,O,X,O,X,X,X,O,O,X,O,X,X,O,X,X,X,X,X,O,X,X,O,O,O,X,X,X,X,O,X,X,X,X,X,X,X,X,X,O,X,O,O,O,O,X,O,O,O,O,X,O,O,O,O,O,O,X,O,X,X,X,O,O,O,X,X,O,O,O,X,X,X,O,X,X,X,X,O,O,X },
	{ X,O,O,X,X,O,O,X,O,O,O,O,X,X,O,X,X,O,O,O,O,X,X,O,O,O,O,O,O,X,O,O,O,O,X,X,X,O,O,X,X,O,O,O,O,O,O,X,O,X,X,O,O,O,O,O,O,X,X,X,O,X,O,O,O,O,X,O,X,X,X,O,O,X,O,X,O,X,O,O,X,X,X,O },
	{ X,X,X,X,X,X,O,O,O,O,O,X,O,O,X,O,X,O,X,O,X,O,O,O,O,O,O,X,O,X,O,X,O,X,O,X,O,X,O,O,X,X,X,O,O,O,X,O,O,X,O,X,O,X,O,O,X,X,O,X,X,X,O,O,X,X,O,X,X,X,O,X,X,X,X,X,X,O,O,O,O,O,O,O },
	{ X,X,X,O,X,O,O,O,O,X,O,O,X,O,X,O,X,O,X,X,O,X,O,O,X,X,X,O,O,O,O,O,X,O,X,X,X,O,O,O,X,X,X,O,O,O,O,O,X,O,X,O,O,X,X,X,X,O,O,O,O,X,O,X,X,O,O,X,O,O,O,X,X,O,O,O,X,X,X,X,O,O,X,O },
	{ O,X,X,X,X,X,X,X,O,X,O,O,X,O,X,X,O,O,X,X,X,O,O,O,O,X,X,X,X,O,O,O,O,X,X,O,X,X,O,O,X,O,X,O,X,O,X,X,O,X,O,O,O,X,O,X,O,X,O,O,O,X,X,O,O,X,X,O,O,X,X,X,O,X,X,O,X,O,O,X,X,X,O,O },
	{ O,O,X,X,X,X,X,X,X,X,O,X,X,O,X,O,O,O,O,O,X,X,X,X,O,X,O,X,X,O,X,X,O,X,X,O,O,X,O,X,O,O,O,X,O,X,O,X,X,X,X,X,O,X,O,O,X,O,O,X,X,X,X,O,X,O,X,O,O,X,O,O,O,O,O,X,O,X,O,O,O,O,O,X },
	{ O,X,O,X,X,O,X,X,X,O,X,X,X,O,O,X,O,X,O,O,X,O,O,O,O,O,O,O,O,X,X,O,O,X,O,O,O,O,X,X,O,O,O,X,X,X,X,O,O,O,X,O,O,X,X,X,O,X,O,X,X,X,X,X,X,X,O,O,O,O,X,X,X,O,O,O,X,X,X,X,X,X,O,X },
	{ O,O,X,X,O,O,X,O,X,O,X,O,O,O,O,X,O,O,X,O,X,O,X,O,O,X,X,O,O,X,X,O,O,O,X,X,X,O,O,O,X,X,O,O,X,X,O,O,O,O,X,O,O,O,O,O,O,X,O,O,X,X,X,O,X,O,X,X,X,O,X,O,X,O,O,O,X,X,X,X,O,O,O,X },
};

const char zhResMat[31][84] = 
{
	{ O,X,O,O,O,O,O,X,X,O,X,X,O,X,O,O,O,X,O,X,X,X,O,X,O,O,X,O,X,O,O,O,X,X,O,O,X,X,X,O,O,X,X,O,X,O,X,X,X,X,X,X,X,X,O,X,O,O,X,X,X,O,X,X,O,O,X,O,X,O,O,X,O,X,X,O,X,O,O,X,O,O,O,X },
	{ X,O,O,O,O,X,O,X,X,O,O,O,O,O,X,X,O,X,X,X,X,X,X,O,O,O,X,X,O,X,O,O,O,O,O,X,O,O,X,O,O,O,O,O,X,X,O,O,X,X,X,O,O,O,O,O,O,X,O,O,O,O,O,X,O,X,O,X,O,O,O,X,O,O,X,X,X,O,O,X,O,O,X,O },
	{ O,X,O,X,O,O,X,O,X,X,O,X,X,X,O,O,O,O,X,X,X,O,O,X,O,X,O,O,O,O,O,O,X,X,X,X,X,X,O,X,O,O,X,O,O,O,X,X,O,X,X,X,X,O,X,X,X,O,O,X,X,O,X,X,O,X,X,O,X,O,X,O,X,O,X,O,O,O,X,O,X,X,X,O },
	{ X,O,O,O,O,X,X,O,X,X,X,O,X,O,X,O,X,X,O,X,X,O,O,O,O,X,X,O,X,O,X,X,O,O,X,X,X,O,X,O,X,X,X,O,X,X,X,X,O,X,O,O,X,O,O,X,O,O,O,X,X,X,O,O,O,O,O,O,X,O,X,O,X,O,X,X,O,O,O,O,X,O,O,X },
	{ O,O,O,X,X,O,X,X,O,X,X,O,X,X,O,O,O,X,X,X,O,X,X,O,O,X,O,X,O,X,X,X,X,O,X,O,O,O,X,O,X,O,O,O,X,O,X,X,X,X,O,X,O,X,O,O,X,O,O,O,X,O,O,X,X,O,O,O,O,X,X,O,O,O,X,X,O,X,X,O,X,O,O,X },
	{ O,X,O,O,X,X,X,X,O,O,X,O,X,O,O,O,X,X,O,X,O,O,O,X,O,O,O,X,O,O,X,X,O,O,O,O,X,O,X,X,O,X,X,X,X,X,X,O,O,X,X,O,X,O,X,X,X,O,X,X,O,O,O,O,O,X,O,X,O,X,O,O,X,X,O,O,X,O,X,X,X,O,O,O },
	{ X,X,O,X,O,X,X,X,X,O,O,X,O,X,O,X,X,X,O,X,O,X,X,X,O,O,X,O,O,X,O,X,X,O,O,O,O,X,X,X,O,X,O,O,X,O,X,O,X,X,X,X,O,X,O,X,X,O,O,O,X,O,O,O,O,O,X,O,O,O,O,X,O,O,X,X,O,O,X,X,O,O,X,X },
	{ X,X,O,X,O,O,O,X,X,O,X,O,X,X,O,X,O,O,X,O,O,O,X,X,O,X,O,O,X,X,O,X,O,X,O,X,O,O,X,X,X,X,X,O,O,O,O,X,O,X,O,X,O,X,X,O,O,X,O,O,X,X,O,O,O,X,O,O,O,X,X,O,O,X,X,O,X,O,X,O,O,O,O,O },
	{ X,O,O,O,O,X,O,O,X,O,O,O,X,X,X,O,O,X,X,O,O,X,X,O,X,O,O,O,X,O,O,O,X,O,O,O,X,X,X,X,X,O,X,O,X,O,X,X,X,X,O,O,X,X,O,X,X,O,X,O,O,X,X,X,X,O,X,X,O,X,O,O,O,X,O,X,O,X,O,X,X,X,O,O },
	{ O,O,X,O,O,X,O,O,X,O,X,O,X,O,O,O,X,O,O,X,O,O,X,O,O,O,O,X,O,O,X,O,X,O,X,X,X,X,X,O,O,X,X,X,O,O,X,O,O,O,X,O,O,X,O,X,X,X,X,O,X,X,O,O,X,O,X,X,O,X,O,O,O,X,X,X,X,O,X,X,O,O,O,O },
	{ O,O,X,O,O,O,X,O,X,X,X,O,X,X,O,O,O,O,X,O,O,X,O,X,X,X,O,X,O,X,X,O,O,X,X,X,O,X,X,X,O,O,X,O,O,X,X,X,O,X,X,X,X,X,X,O,O,X,X,O,O,X,X,X,X,O,O,X,O,X,X,X,X,X,O,X,X,O,O,X,O,X,X,X },
	{ O,O,O,X,O,X,X,X,X,O,O,X,X,O,X,X,X,X,X,X,X,X,O,O,X,X,X,O,X,O,O,O,X,X,X,O,O,O,X,O,X,X,O,O,O,X,O,O,O,O,O,X,O,X,O,X,O,X,X,O,O,O,O,X,O,X,O,X,X,X,O,O,X,X,X,X,X,O,X,O,O,O,X,X },
	{ X,O,X,O,X,O,X,X,X,O,X,X,X,X,O,X,X,O,O,X,O,X,O,O,X,X,X,O,O,O,O,X,X,O,X,O,O,O,X,O,O,O,O,O,O,O,X,X,X,X,X,O,O,O,O,O,O,O,X,X,X,O,O,O,O,X,X,O,O,X,O,O,O,O,O,X,X,O,X,O,X,X,O,O },
	{ O,O,X,X,X,O,X,X,O,X,O,X,X,O,X,O,X,X,O,O,X,O,O,O,X,X,X,X,O,O,O,X,X,X,O,O,O,O,O,X,X,O,X,X,O,O,X,O,O,O,X,X,X,X,X,X,O,O,O,O,X,O,X,O,X,O,X,O,O,O,O,O,X,X,O,X,X,O,O,X,O,X,X,O },
	{ X,O,O,X,O,X,X,O,O,O,X,O,O,X,X,O,X,O,O,O,O,O,X,O,X,O,O,X,X,O,O,O,O,X,X,O,X,O,O,X,O,X,O,X,O,X,X,O,O,X,O,X,X,O,O,O,O,X,O,X,O,X,X,X,O,O,X,X,X,O,X,X,X,O,O,O,O,X,O,X,X,X,O,X },
	{ X,X,X,X,X,O,O,X,X,O,O,O,X,O,X,X,O,X,O,X,X,O,X,X,O,X,O,O,X,X,X,O,O,O,O,O,O,O,O,O,O,O,X,X,X,O,X,O,O,O,X,O,X,X,O,X,O,O,X,X,X,O,X,O,O,O,O,X,O,X,O,O,X,X,O,O,X,X,X,O,O,X,X,O },
	{ O,O,X,O,O,X,O,X,O,O,X,O,X,O,X,O,O,O,O,X,O,O,O,X,O,X,O,X,X,O,O,O,X,X,O,O,X,O,X,O,X,X,O,X,X,O,O,X,X,X,X,X,X,O,O,X,X,X,X,O,X,X,X,O,O,O,O,X,O,X,X,O,O,X,O,O,X,O,X,O,O,O,X,X },
	{ O,X,O,O,X,O,O,X,X,X,O,O,X,X,X,X,O,X,O,X,X,X,O,X,O,O,X,X,O,O,O,X,O,O,X,O,O,O,X,O,O,X,X,O,O,O,X,O,O,X,X,O,X,O,X,O,O,X,O,O,X,O,X,X,X,O,O,O,X,O,O,X,X,X,X,O,X,X,O,O,X,X,O,X },
	{ X,O,O,O,X,O,O,X,O,X,O,O,O,O,O,X,O,X,O,X,X,X,X,X,X,X,O,X,X,O,O,O,O,X,O,O,X,X,O,O,X,O,X,X,X,O,O,X,X,O,X,O,O,O,X,X,X,X,X,O,X,X,O,O,O,O,X,O,X,X,O,X,X,X,O,X,X,X,X,X,X,O,X,X },
	{ O,X,X,O,X,O,X,O,X,O,O,X,O,X,O,X,X,X,O,X,O,O,O,X,X,X,X,O,X,O,X,O,X,X,X,O,O,O,X,O,X,O,O,O,O,X,X,O,X,X,X,X,O,O,X,O,X,O,X,X,X,X,O,O,X,X,O,O,X,X,O,O,O,X,X,O,O,O,O,O,X,X,X,X },
	{ O,O,O,O,X,X,X,O,X,O,O,X,O,X,O,X,O,O,O,O,O,O,X,X,O,X,O,X,X,O,O,X,X,O,X,X,O,O,O,X,X,O,O,O,X,X,X,O,X,O,O,X,O,X,X,O,O,O,X,O,O,O,O,O,X,X,O,X,X,O,X,O,O,O,O,X,O,X,X,X,O,X,O,X },
	{ O,O,X,X,O,X,X,O,O,O,O,O,O,O,O,X,X,X,O,X,X,X,X,O,O,O,O,X,X,X,X,O,X,O,X,X,O,O,O,O,X,O,X,O,O,X,O,X,X,O,X,X,X,O,O,X,X,O,X,O,X,O,X,X,X,X,O,O,X,X,X,O,O,O,O,X,X,O,O,O,O,O,O,O },
	{ O,O,X,O,X,O,X,O,O,X,O,O,X,X,O,X,X,X,O,X,O,O,X,O,X,X,O,X,O,X,O,O,O,X,X,O,X,O,O,O,O,X,O,O,X,O,O,X,X,O,X,O,O,X,X,X,X,X,X,O,X,O,O,O,O,X,X,X,O,O,X,O,X,X,O,O,O,O,X,O,X,O,X,X },
	{ O,X,O,X,O,O,O,X,X,X,X,X,X,X,X,X,O,X,O,X,O,X,O,X,O,X,X,O,X,X,O,X,X,O,X,X,X,O,O,O,X,X,X,X,X,X,X,X,X,X,X,O,O,X,X,O,O,O,O,X,X,X,X,X,O,O,O,O,X,O,X,O,O,X,O,O,O,X,O,X,X,O,X,X },
	{ O,X,O,X,X,O,O,X,X,O,O,X,X,O,X,X,O,X,X,X,O,O,X,X,X,X,X,O,X,X,O,O,X,X,X,O,X,O,O,X,O,O,X,O,O,X,X,O,O,X,O,O,O,X,X,X,X,O,O,O,X,X,O,O,X,X,O,O,O,X,O,O,X,X,X,O,O,X,O,X,X,X,X,X },
	{ O,X,X,X,O,X,X,X,X,O,X,O,O,X,O,O,X,X,X,X,X,O,X,O,O,O,X,X,O,O,O,X,X,O,O,O,X,O,X,O,O,X,X,X,X,O,X,X,O,O,X,X,O,X,X,O,X,X,O,O,X,X,X,X,X,O,O,X,O,O,X,X,O,X,X,O,X,X,X,X,X,O,X,X },
	{ X,X,O,O,X,X,O,O,O,X,X,X,O,O,X,O,X,X,O,X,O,X,X,X,X,X,O,O,O,O,O,X,O,X,X,X,X,O,X,O,O,O,O,O,O,X,O,X,O,X,X,X,X,X,O,O,O,X,O,X,O,X,X,O,O,X,X,O,O,O,O,O,O,X,O,X,O,O,X,O,X,X,X,O },
	{ X,O,O,O,O,O,X,O,O,O,O,O,O,O,X,O,O,O,O,O,O,X,O,O,O,X,X,O,X,O,O,O,O,X,O,X,X,X,X,O,O,O,O,O,X,X,X,X,X,X,X,O,X,O,X,O,X,O,O,O,X,O,X,O,X,X,O,O,X,X,O,X,O,O,O,O,X,O,X,X,O,O,O,O },
	{ O,X,O,O,O,X,X,O,X,O,X,O,O,O,O,X,X,O,O,X,X,X,X,O,X,X,X,X,O,O,O,X,O,O,O,X,O,X,O,X,O,O,O,X,O,X,X,X,X,O,O,O,X,O,X,O,O,X,X,O,X,X,X,O,X,O,O,O,X,O,O,O,X,X,X,X,O,X,O,X,O,O,O,O },
	{ X,X,O,O,O,O,O,O,X,O,O,O,O,O,X,X,X,X,X,O,O,X,X,O,X,X,O,X,X,X,O,O,O,O,O,O,O,X,X,X,X,O,O,X,X,O,X,X,O,O,X,O,X,O,O,X,X,X,X,X,O,O,X,O,X,X,O,X,O,X,X,X,O,X,X,O,X,O,X,X,O,O,O,X },
	{ X,O,O,O,X,X,X,O,X,X,X,X,X,X,X,X,O,O,O,X,X,O,X,O,X,O,X,O,X,O,X,O,O,O,X,O,O,O,X,X,O,O,O,O,O,X,O,X,X,O,X,O,O,X,X,X,O,X,O,X,X,O,X,X,X,O,O,X,O,X,X,O,X,O,X,O,O,O,X,O,O,X,O,X },
};

void save_file(CNN *cnn,const char *filename,const char (*resMat)[OUTPUT],const int lenMat)
{
	FILE *fp = fopen(filename, "wb");
	fwrite(cnn, 1, sizeof(CNN), fp);
	fwrite(resMat, 1, lenMat, fp);
	fclose(fp);
}

long read_files(const char *imagefile, const char *labelfile, image **images, uint8 **labels)
{
	FILE *fp = fopen(labelfile, "rb");
	long count = 0;
	if (!fp) return 0;
	fseek(fp, 0, SEEK_END);
	count = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	*labels = (uint8 *)calloc(count, sizeof(uint8));
	fread(*labels, sizeof(uint8), count, fp);
	fclose(fp);
	fp = fopen(imagefile, "rb");
	if (!fp)
	{
		free(*labels);
		return 0;
	}
	*images = (image *)calloc(count, sizeof(image));
	fread(*images, sizeof(**images), count, fp);
	fclose(fp);
	return count;
}

void train_datas(CNN *cnn,image *images, uint8 *labels,const char (*resMat)[OUTPUT],long count, int batch)
{
	for (int i = 0, percent = 0; i <= count - batch; i += batch)
	{
		TrainBatch(cnn, images + i, resMat, labels + i, batch);
		percent = i * 100 / count;
		printf("batch:%d\tpercent:%02d%%\n", batch, percent);
	}
	printf("batch:%d\tpercent:100%%\n", batch);
}

void test_datas(CNN *cnn, image *images, uint8 *labels,const char (*resMat)[OUTPUT],uint8 resRows, long count)
{
	int error = 0;
	for (int i = 0; i < count; ++i)
	{
		uint8 result = Predict(cnn, images[i], resMat, resRows);
		error += result != labels[i];
	}
	printf("errors:%d/%d\n", error, count);
}

void test_en(void)
{
	uint8 *labels = 0;
	image *images = 0;
	
	long count = read_files(EN_IMAGE_FILE, EN_LABEL_FILE, &images, &labels);
	CNN cnn = { 0 };
	Initial(&cnn);
	srand(time(0));
	for (int i = 0; i < 20; ++i)
        train_datas(&cnn, images, labels, enResMat,count, rand() % 200 + 100);
	test_datas(&cnn, images, labels, enResMat,34,count);
	save_file(&cnn, "en-cnn.dat", enResMat, sizeof(enResMat));
	free(labels);
	free(images);
	system("pause");		
}

void test_zh(void)
{
	uint8 *labels = 0;
	image *images = 0;
	long count = read_files(ZH_IMAGE_FILE, ZH_LABEL_FILE, &images, &labels);
	CNN cnn = { 0 };
	Initial(&cnn);
	srand(time(0));
	for (int i = 0; i < 30; ++i)
		train_datas(&cnn, images, labels, zhResMat,count, rand() % 100 + 50);
	test_datas(&cnn, images, labels,zhResMat,31, count);
	save_file(&cnn, "zh-cnn.dat", zhResMat, sizeof(zhResMat));
	free(labels);
	free(images);
	system("pause");
}



int main(void)
{
	test_en();
	return 0;
}
